package edu.uoc.tdp.pac4.beans;

import java.awt.Image;
import java.awt.Toolkit;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;

/**
 * Classe que emmagatzema les dades basiques d'identificaci� d'una persona
 * amb DNI. Implementa els m�todes compare(obj1,obj2) i equals(obj2) de
 * l'interface Comparator per a facilitar l'ordenaci� de les Collections de
 * persones, pel seu DNI, aix� com l'interface Serializable per a facilitar
 * la persist�ncia dels seus atributs.
 *
 * @version  1.0b; 30-04-2000; java version "1.2.2";  Classic VM (build
 * JDK-1.2.2-001, native threads, symcijt)
 * @author   TDP
 */

/**
 * Nous canvis introdu�ts per TDP QP2001
 */

public abstract class Persona implements Comparator, java.io.Serializable {

	private static final long serialVersionUID = 1L;

	/** Atribut que cont� la lletra del NIF de la persona */
	protected String NumIdFiscal;
	/** Variable que cont� el sexe de la persona */
	protected Sex sexe;
	/** Atribut que cont� el nom de la persona */
	protected String cli_nombre;
	/** Atribut que cont� els cognoms de la persona */
	protected String cli_apellidos;
	/** Atribut que contiene la fecha de nacimiento de la persona */
	protected Date cli_nacimiento;
	/** Atribut que cont� l'adre�a de correu electr�nic d'una persona */
	protected String email;

	
	
	/** Atribut que cont� el path/nom.ext de l'arxiu de la fotografia */
	private String foto = "imatges/";
	/** Atribut que cont� el DNI de la persona */
	private int DNI = 0;
	private final DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

	/** Atributo que contiene la direcci�n de la persona */
	private String cli_direccion;
	/** Atributo que contiene la localidad de la persona */
	private String cli_localidad;
	/** Atributo que contiene la provincia de la persona */
	private String cli_provincia;
	/** Atributo que contiene el pa�s de la persona */
	private String cli_pais;
	/** Atributo que contiene el distrito postal de la persona */
	private String cli_dp;
	/** Atributo que contiene el idioma de la persona */
	private String cli_idioma;

	/** Atribut que cont� la taula de lletres dels NIFs */
	private static final char[] lletra = { 'T', 'R', 'W', 'A', 'G', 'M', 'Y',
			'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L',
			'C', 'K', 'E' };

	/**
	 * Constructor amb cinc par�metres. Emmagatzema el DNI, la lletra del NIF,
	 * el nom, els cognoms, l'adre�a d'email i la data de maixement d'una
	 * persona. {Pre: dni �s un enter estrictament positiu que representa el DNI
	 * d'una persona} {Post: s'ha creat una inst�ncia de la classe Persona. Si
	 * no es compleix la precondici�, s'ha donat un valor zero al DNI}
	 * 
	 * @param dni
	 *            representa el DNI d'una persona.
	 * @see Persona#setIdentitat(String,String,String,Date, Sexe)
	 */
	public Persona(String numIdFiscal, String email, String cli_nombre,
			String cli_apellidos, Date dataNaix, Sex sexe) {
		if (NIF.validar(numIdFiscal))
			NumIdFiscal = numIdFiscal;
		else
			NumIdFiscal = " ";

		setIdentitat(cli_nombre, cli_apellidos, email, cli_nacimiento, sexe);
	}

	public Persona() {

	}

	/**
	 * Accessor d'escriptura dels atributs. Desa el DNI, la lletra del NIF, el
	 * tractament, el nom, els cognoms i la data de maixement d'una persona.
	 * {Pre: dni �s un enter estrictament positiu que representa el DNI d'una
	 * persona; el tractament i la fecha de nacimiento s�n no nuls} {Post: s'ha
	 * creat una inst�ncia de la classe Persona. Si no es compleix la
	 * precondici�, s'ha donat un valor zero al DNI, Sr. al tractament i data
	 * actual a la fecha de nacimiento, respectivament}
	 * 
	 * @param sexe
	 *            representa el sexe de la persona
	 * @param nom
	 *            representa el nom de la persona.
	 * @param cli_apellidos
	 *            representa els cognoms de la persona.
	 * @param cli_nacimiento
	 *            representa la fecha de nacimiento de la persona i,
	 *            indirectament, la seva edat.
	 */
	public void setIdentitat(String cli_nombre, String cli_apellidos,
			String email, Date cli_nacimiento, Sex sexe) {
		this.cli_nombre = cli_nombre;
		this.cli_apellidos = cli_apellidos;
		this.sexe = sexe;
		this.email = email;
		setNacimiento(cli_nacimiento);
	}

	/**
	 * Accessor de lectura del NIF de la persona.
	 * 
	 * @return NumIdFiscal.
	 */
	public String getNIF() {

		return NumIdFiscal;
	}

	public void setNIF(String numIdFiscal) {
		NumIdFiscal = numIdFiscal;
	}

	/**
	 * Accessor d'escriptura de l'email de la persona.
	 * 
	 * @param emailAdr
	 *            .
	 */
	public void setEmail(String emailAdr) {
		this.email = emailAdr;
	}

	/**
	 * Accessor de lectura de l'email de la persona.
	 * 
	 * @return email.
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * Accessor d'escriptura de la fotografia de la persona.
	 * 
	 * @param foto
	 *            path/nom.ext de l'arxiu de la fotografia de la persona.
	 */
	public void setFoto(String foto) {
		this.foto = foto;
	}

	/**
	 * Accessor de lectura de la fotografia de la persona.
	 * 
	 * @return path/nom.ext de l'arxiu de la fotografia de la persona.
	 */
	public String getFoto() {
		return (new String(foto));
	}

	/**
	 * Accessor de lectura de la fotografia de la persona.
	 * 
	 * @return fotografia de la persona.
	 */
	public Image getFotoImatge() {
		return Toolkit.getDefaultToolkit().getImage(foto);
	}

	/**
	 * Accessor d'escriptura del nom de la persona.
	 * 
	 * @param cli_nombre
	 *            representa el nom de la persona.
	 */
	public void setNombre(String cli_nombre) {
		this.cli_nombre = cli_nombre;
	}

	/**
	 * Accessor de lectura del nom de la persona.
	 * 
	 * @return nombre de la persona.
	 */
	public String getNombre() {
		return cli_nombre;
	}

	/**
	 * Accessor d'escriptura dels cognoms de la persona.
	 * 
	 * @param cli_apellidos
	 *            representa els cognoms de la persona.
	 */
	public void setApellidos(String cli_apellidos) {
		this.cli_apellidos = cli_apellidos;
	}

	/**
	 * Accessor de lectura dels cognoms de la persona.
	 * 
	 * @return cognoms de la persona.
	 */
	public String getApellidos() {
		return cli_apellidos;
	}

	/**
	 * Accessor de lectura del sexe de la persona {Pre: x �s una inst�ncia d'una
	 * subclasse de Persona} {Post: retorna el sexe de x}
	 * 
	 * @author Java22; 31-5-2001
	 * @return String - el sexe de la persona
	 */
	public Sex getSexe() {
		return sexe;
	}

	/**
	 * Accessor d'escriptura per assignar o canviar el sexe a la persona. {Pre:
	 * x �s una inst�ncia d'una subclasse de Persona i pSexe �s alguna de les
	 * cadenes definides a la constant SEXE} {Post: assigna a l'atribut sexe el
	 * sexe de x}
	 * 
	 * @author Java22; 31-5-2001
	 * @param pSexe
	 *            �s el sexe de la persona.
	 */
	public void setSexe(Sex pSexe) {
		sexe = pSexe;
	}



	/**
	 * Accessor de escritura de la direcci�n de la persona.
	 * 
	 * @param cli_direccion
	 *            representa la direcci�n de la persona.
	 */
	public void setDireccion(String cli_direccion) {
		this.cli_direccion = cli_direccion;
	}

	/**
	 * Accessor de lectura de la direcci�n de la persona.
	 * 
	 * @return direcci�n de la persona.
	 */
	public String getDireccion() {
		return cli_direccion;
	}

	/**
	 * Accessor de escritura de la localidad de la persona.
	 * 
	 * @param cli_localidad
	 *            representa la localidad de la persona.
	 */
	public void setLocalidad(String cli_localidad) {
		this.cli_localidad = cli_localidad;
	}

	/**
	 * Accessor de lectura de la localidad de la persona.
	 * 
	 * @return direcci�n de la persona.
	 */
	public String getLocalidad() {
		return cli_localidad;
	}

	/**
	 * Accessor de escritura de la provincia de la persona.
	 * 
	 * @param cli_direccion
	 *            representa la provincia de la persona.
	 */
	public void setProvincia(String cli_provincia) {
		this.cli_provincia = cli_provincia;
	}

	/**
	 * Accessor de lectura de la provincia de la persona.
	 * 
	 * @return provincia de la persona.
	 */
	public String getProvincia() {
		return cli_provincia;
	}

	/**
	 * Accessor de escritura del pa�s de la persona.
	 * 
	 * @param cli_pa
	 *            �s representa el pa�s de la persona.
	 */
	public void setPais(String cli_pais) {
		this.cli_pais = cli_pais;
	}

	/**
	 * Accessor de lectura del pais de la persona.
	 * 
	 * @return pais de la persona.
	 */
	public String getPais() {
		return cli_pais;
	}

	/**
	 * Accessor de escritura del distrito postal de la persona.
	 * 
	 * @param cli_direccion
	 *            representa el distrito postal de la persona.
	 */
	public void setDP(String cli_dp) {
		this.cli_dp = cli_dp;
	}

	/**
	 * Accessor de lectura del distrito postal de la persona.
	 * 
	 * @return distrito postal de la persona.
	 */
	public String getDP() {
		return cli_dp;
	}

	/**
	 * Accessor de escritura del idioma de la persona.
	 * 
	 * @param cli_idioma
	 *            representa el idioma que utiliza la persona.
	 */
	public void setIdioma(String cli_idioma) {
		this.cli_idioma = cli_idioma;
	}

	/**
	 * Accessor de lectura del idioma que utiliza la persona.
	 * 
	 * @return idioma de la persona.
	 */
	public String getIdioma() {
		return cli_idioma;
	}

	/**
	 * Accessor d'escriptura de la fecha de nacimiento de la persona.
	 * 
	 * @param cli_nacimiento
	 *            representa la fecha de nacimiento de la persona.
	 */
	public void setNacimiento(Date cli_nacimiento) {
		this.cli_nacimiento = cli_nacimiento;
	}

	/**
	 * Accessor de lectura de la fecha de nacimiento de la persona.
	 * 
	 * @return fecha de nacimiento o null.
	 */
	public Date getNacimiento() {
		return this.cli_nacimiento;
	}
	

	/**
	 * M�tode que calcula l'ordre de dos objectes que representen persones, en
	 * base a l'ordre dels respectius DNIs. {Pre: obj1 i obj2 representen
	 * objectes que es poden convertir a Persones amb un cast} {Post: s'ha
	 * retornat l'ordre (ascendent) de l'objecte1 pel seu DNI}
	 * 
	 * @param obj1
	 *            objecte que representa la 1a persona amb NIF.
	 * @param obj2
	 *            objecte que representa la 2a persona amb NIF.
	 * @return 0 -> obj1 igual NIF que obj2; -1 -> obj1 abans obj2; 1 -> obj1
	 *         despr�s obj2.
	 */
	public int compare(Object obj1, Object obj2) // implementa Comparator
	{
		String pnif1 = ((Persona) obj1).getNIF();
		String pnif2 = ((Persona) obj2).getNIF();
		long num1 = Long.parseLong(pnif1.substring(0, 7));
		long num2 = Long.parseLong(pnif2.substring(0, 7));
		if (num1 < num2)
			return -1;
		if (num1 > num2)
			return 1;
		return 0;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((NumIdFiscal == null) ? 0 : NumIdFiscal.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Persona other = (Persona) obj;
		if (NumIdFiscal == null) {
			if (other.NumIdFiscal != null)
				return false;
		} else if (!NumIdFiscal.equals(other.NumIdFiscal))
			return false;
		return true;
	}

	/**
	 * M�tode que comprova si dos objectes que representen persones s�n iguals,
	 * en base als respectius NIFs. {Pre: x �s una inst�ncia de Persona i obj2
	 * representa un objecte que es pot convertir a Persona amb un cast} {Post:
	 * s'ha retornat un boole� que indica si x �s igual a objecte2}
	 * 
	 * @param obj2
	 *            objecte que representa l'altra persona.
	 * @return cert -> x igual NIF que obj2; fals -> altrament.
	 */
	

}
